/*

  图书馆系统处理件

  接入图书馆系统的模块

*/

class h_library {

	async libraryLogin(stuId, stuPwd, user) {
		if(this._checkLibraryLogin(user, stuId))
			return user
		const result = await this.common.reqPost({
			url: `${this.config.library.url}unionlib/opac/servlet/opac.go`,
			headers: {
				'content-type': 'application/x-www-form-urlencoded'
			},
			data: {
				cmdACT: 'mylibrary.login',
				libcode: '',
				userid: stuId,
				passwd: stuPwd
			},
			getCookie: true,
			notFollow:  true
		})
		if(!result.cookie[0] || !result.cookie[0]['JSESSIONID']) {
			await this._libraryLogout(user)
			return this.reject('-3040', 'library login failed')
		}
		const librarySession = result.cookie[0]['JSESSIONID']
		let cookie = {}
		cookie[this.config.library.url] = {
			JSESSIONID: librarySession
		}
		const result2 = await this.common.reqGet({
			url: `${this.config.library.url}unionlib/opac/servlet/opac.go`,
			cookie,
			data: {
				cmdACT: 'reader.info'
			},
			getStatus: true
		})
		const {status, data} = result2
		if(status.code != 200) {
			await this._libraryLogout(user)
			return this.reject('-3040', 'library login failed')
		}
		if(/未登陆系统/.test(data)) {
			await this._libraryLogout(user)
			return this.reject('-3040', 'library login failed')
		}
		const libraryData = {
			userId: stuId,
			logined: true,
			session: librarySession,
			time: parseInt(Date.now() / 1000)
		}
		await this.updateLibraryUserData(libraryData)
		await this.common.updateSessionData(user.session, {
			library: libraryData
		})
		user.data.library = libraryData
		console.log(libraryData)
		return user
	}

	async getReaderDataByUserId(userId) {
		
	}

	async updateLibraryUserData(libraryData) {

	}

	async searchBook(searchMode, searchContent, pageIndex = 0) {
		if(!searchContent)
			return {}
		const filterStr = this.config.library.filterMap[searchMode] ||this.config.library.filterMap['name']
		const result = await this.common.reqPost({
			url: `${this.config.library.url}unionlib/opac/servlet/opac.go`,
			headers: {
				'content-type': 'application/x-www-form-urlencoded'
			},
			data: {
				cmdACT: 'page.list',
				FILTER: filterStr.replace(/{{content}}/, encodeURIComponent(searchContent.toUpperCase())),
				PAGE: isNaN(pageIndex) ? 1 : pageIndex,
				bookid: '',
				SORTFIELD: '',
				SORTORDER: '',
				PAGESIZE: '',
				libcode: ''
			},
			getStatus: true
		})
		const {status, data} = result
		console.log(data)
		if(status.code != 200) 
			return this.reject('-3045', 'library search failed')
		const $ = this.common.parseHTML(data)
		const filter = $('input[name="FILTER"]').val().trim()
		const list = $('tbody').eq(10).children('tr')
		if(list.length < 2 || /查无符合条件的记录/.test(list.text()))
			return []
		let resultList = []
		list.each(function(index) {
			if(index == 0)
				return
			const item = $(this).children('td')
			const temp = item.eq(1).html().match(/book_detail\((\d+)\)/)
			if(!temp[1])
				return
			resultList.push({
				bookId: temp[1],
				bookName: item.eq(1).text().trim(),
				bookAuthor: item.eq(2).text().trim(),
				bookPublish: item.eq(3).text().trim()
			})
		})
		console.log(resultList)
		return resultList
	}

	async getBookData(bookId, user) {
		const result = await this.common.reqGet({
			url: `${this.config.library.url}unionlib/opac/servlet/opac.go`,
			// cookie,
			data: {
				cmdACT: 'query.bookdetail',
				bookid: bookId,
				marcformat: '',
				libcode: '',
				source: ''
			},
			getStatus: true
		})
		const {status, data} = result
		if(status.code != 200) {
			return this.reject('-3046', 'get library book data failed')
		}
		const $ = this.common.parseHTML(data, false)
		const temp = $('tbody').eq(11).children('tr').children('td')
		const keyMap = {
			'题名': 'bookName',
			'附加题名': 'bookAttachName',
			'丛编项': 'bookSeries',
			'主要责任者': 'bookAuthor',
			'其他责任者': 'bookOtherAuthor',
			'出版资料': 'bookPublish',
			'载体形态': 'bookShape',
			'附注': 'bookRemark',
			'主题': 'bookLabel',
			'中图分类': 'bookClassNum',
			'ISBN': 'bookISBN',
			'索书号': 'bookCallNum',
			'随书光盘：': 'bookCD'
		}
		let bookData = {
			bookHoldList: [],
			bookOutList: []
		}
		let tempKey = ''
		temp.each(function(index) {
			if(tempKey == 'unknown')
				return
			if(index % 2 == 0) {
				const key = $(this).text().trim()
				if(!keyMap[key])
					tempKey = 'unknown'
				else
					tempKey = keyMap[key]
				return
			}
			bookData[tempKey] = $(this).text().trim()
		})
		const temp2 = $('#queryholding tbody tr table tbody tr')
		temp2.each(function(index) {
			if(index == 0)
				return
			const item = $(this).children('td')
			const _temp = item.eq(6).text().trim()
			const bookStatus = ['借出', '在馆'].indexOf(item.eq(5).text().trim())
			if(bookStatus == 0) {
				bookData.bookOutList.push({
					bookNum: item.eq(0).text().trim(),
					bookAddress: item.eq(3).text().trim(),
					bookReturnDate: _temp ? parseInt(Date.parse(item.eq(6).text().trim()) / 1000) : -1
				})
			}
			else if(bookStatus == 1) {
				bookData.bookHoldList.push({
					bookNum: item.eq(0).text().trim(),
					bookAddress: item.eq(3).text().trim(),
					bookReturnDate: _temp ? parseInt(Date.parse(item.eq(6).text().trim()) / 1000) : -1
				})
			}
		})
		if(!bookData['bookName'])
			return this.reject('-3046', 'get library book data failed')
		//处理书名
		bookData['bookName'] = ((bookData['bookName'].split('/'))[0].trim().split('='))[0].trim()
		//处理ISBN号和价格
		if(bookData['bookISBN']) {
			const str = bookData['bookISBN'].split(' ')
			bookData['bookISBN'] = str[0].trim()
			if(str[1])
				bookData['bookPrice'] = (str[1].trim().match(/^价格:(.+)/))[1]
			bookData['bookCover'] = await this._getBookCoverByISBN(bookData['bookISBN'])
		}
		await this.redis.cache.set(`book@${bookId}`, bookData, this.config.frame.sessionExpires.library)
		return bookData
	}

	async getLoanCache(userId) {
		let loanData = await this.redis.cache.get(`loan@${userId}`, true)
		if(loanData)
			return loanData
		return false
	}

	async getLoan(user) {
		if(!this._checkLibraryLogin(user))
			return this.reject('-3041', 'library user not logined in')
		const {session} = user.data.library
		let cookie = {}
		cookie[this.config.library.url] = {
			JSESSIONID: session
		}
		const result = await this.common.reqGet({
			url: `${this.config.library.url}unionlib/opac/servlet/mylib.go`,
			cookie,
			data: {
				cmdACT: 'loan.list'
			},
			getStatus: true
		})
		const {status, data} = result
		if(status.code != 200) {
			await this._libraryLogout(user)
			return this.reject('-3040', 'library login failed')
		}
		let loanList = []
		const $ = this.common.parseHTML(data, false)
		const list = $('tbody').eq(7).children('tr')
		//是否无借阅记录
		console.log(list.html(), list.length)
		if(list.length < 2 || /当前没有借阅/.test(list.text())) {
			await this.redis.cache.set(`loan@${user.userId}`, [], this.config.frame.sessionExpires.library)
			return []
		}
		list.each(function(index) {
			if(index == 0)
				return
			const item = $(this).children('td')
			const idTemp = item.eq(1).children('a').attr('href').match(/bookid=(\d+)&/)
			let temp = item.eq(1).text().trim().split('/')
			if(!temp || !temp[0])
				temp = ['unknown', 'unknown']
			else if(!temp[1])
				temp = [temp[0], 'unknown']
			const temp2 =  item.eq(7).text().trim().split('/')
			loanList.push({
				bookId: idTemp[1],
				bookNum: item.eq(0).text().trim(),
				bookName: temp[0],
				bookAuthor: temp[1],
				bookAddress: item.eq(4).text().trim(),
				bookLoanDate: parseInt(Date.parse(item.eq(5).text().trim()) / 1000),
				bookReturnDate: parseInt(Date.parse(item.eq(6).text().trim()) / 1000),
				bookReloanCount: temp2[0],
				bookMaxReloanCount: temp2[1],
				bookExpire: ['否', '是'].indexOf(item.eq(8).text().trim())
			})
		})
		await this.redis.cache.set(`loan@${user.userId}`, loanList, this.config.frame.sessionExpires.library)
		return loanList
	}

	async clearUserLibraryLoanCache(userId) {
		return await this.redis.cache.delete(`loan@${userId}`)
	}

	async getBookCoverByISBN(ISBN) {
		return await this._getBookCoverByISBN(ISBN)
	}

	async reloanBook(bookNum, user) {
		if(!this._checkBookNum(bookNum))
			return this.reject('-3042', 'book num invalid')
		const {session} = user.data.library
		let cookie = {}
		cookie[this.config.library.url] = {
			JSESSIONID: session
		}
		const result = await this.common.reqGet({
			url: `${this.config.library.url}unionlib/opac/servlet/opac.go`,
			cookie,
			data: {
				cmdACT: 'mylibrary.reloan',
				BARCODE: bookNum,
				libcode: ''
			},
			getStatus: true
		})
		const {status, data} = result
		if(status.code != 200) {
			await this._libraryLogout(user)
			return this.reject('-3040', 'library login failed')
		}
		if(/读者有超期未还的书！/.test(data))
			return this.reject('-3043', 'book is expire not reloan')
		if(/读者可续借/.test(data))
			return 1
		else
			return this.reject('-3044', 'book reloan failed')
	}

	async getBookCache(bookId) {
		const bookInfo = await this.redis.cache.get(`book@${bookId}`, true)
		if(bookInfo)
			return bookInfo
		return false
	}

	async _getBookCoverByISBN(ISBN) {
		//从豆瓣获取封面
		ISBN = ISBN.replace(/-/g, '')
		const result = await this.common.reqGet({
			url: `https://api.douban.com/v2/book/isbn/${ISBN}`
		})
		return result.image || `${this.config.server.staticUrl}cxxy/image/error/image-404.jpg`
	}

	async _libraryLogout(user) {
		user.data.library = {
			logined: false,
			session: undefined,
			time: 0
		}
		await this.common.updateSessionData(user.session, {
			library: user.data.library
	 	})
	}

	_checkBookNum(bookNum) {
		return /^(\w+){8}$/.test(bookNum)
	}

	_checkLibraryLogin(user, userId) {
		console.log(user)
		if(!user.data || !user.data.library || !user.data.library.logined || !user.data.library.session || !user.data.library.time || (parseInt(Date.now() / 1000) - user.data.library.time) > this.config.frame.sessionExpires.library || (userId && userId != user.data.library.userId)) {
			console.error('library user not login')
			return false
		}
		console.log('library user logined')
		return true
	}

}

module.exports = h_library